//Font.c: Display Chinese word and ASCII code
//Code by luobing 2019-5-16 15:48:50
/**
 * 《UEFI编程实践》随书代码
 * 更多的UEFI探索，可以参考笔者的博客和专栏：
 * CSDN: https://blog.csdn.net/luobing4365
 * 知乎: https://www.zhihu.com/column/c_1233025362843209728
 * **/
//#include "Window.h"
#include "Graphic.h"
#include "Font.h"

/*================================================= Chinese words =========================================================*/
//===================UTF-8 汉字 字模 begin================================================
//UTF-8 数据
UINT8 _46_27[] = {
0, 96, 73, 1, 255, 1, 197, 1, 0, 2, 73, 1, 255, 1, 197, 1, 0, 31, };
UINT8 _49_27[] = {
0, 78, 153, 1, 255, 1, 0, 8, 197, 1, 255, 3, 0, 6, 153, 1, 255, 2, 153, 1, 255, 2, 0, 6, 153, 1, 197, 1, 0, 2, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 10, 255, 2, 0, 76, };
UINT8 _15041929_27[] = {
0, 109, 111, 1, 255, 1, 0, 11, 73, 1, 153, 1, 0, 5, 111, 1, 255, 1, 0, 5, 36, 1, 197, 1, 0, 4, 111, 1, 255, 1, 111, 1, 0, 4, 111, 1, 255, 1, 0, 5, 197, 1, 255, 1, 73, 1, 0, 4, 111, 1, 255, 1, 36, 1, 0, 3, 111, 1, 255, 1, 0, 4, 153, 1, 255, 1, 73, 1, 0, 6, 197, 1, 255, 1, 0, 3, 111, 1, 255, 1, 0, 3, 111, 1, 255, 1, 73, 1, 0, 7, 36, 1, 255, 1, 197, 1, 0, 2, 111, 1, 255, 1, 0, 2, 73, 1, 255, 1, 111, 1, 0, 9, 111, 2, 0, 2, 111, 1, 255, 1, 0, 2, 153, 1, 111, 1, 0, 14, 111, 1, 255, 1, 0, 9, 36, 1, 255, 18, 197, 1, 0, 6, 111, 1, 255, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 12, 111, 1, 255, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 12, 153, 1, 197, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 12, 255, 1, 153, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 4, 111, 1, 197, 1, 0, 5, 73, 1, 255, 1, 36, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 4, 111, 1, 255, 1, 0, 5, 255, 1, 153, 1, 0, 4, 36, 1, 255, 1, 73, 1, 0, 4, 153, 1, 255, 1, 0, 4, 255, 1, 197, 1, 0, 6, 255, 1, 111, 1, 0, 4, 255, 1, 197, 1, 0, 2, 153, 1, 255, 1, 153, 1, 0, 7, 111, 1, 255, 6, 36, 1, 73, 1, 255, 1, 197, 1, 0, 97, };
UINT8 _15050173_27[] = {
0, 103, 153, 1, 197, 1, 0, 18, 197, 1, 153, 1, 0, 3, 73, 1, 255, 10, 73, 1, 0, 3, 255, 1, 111, 1, 0, 11, 111, 1, 255, 1, 197, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 10, 153, 1, 255, 1, 197, 1, 0, 2, 111, 1, 255, 7, 0, 6, 197, 1, 255, 1, 153, 1, 0, 5, 111, 1, 197, 1, 0, 2, 111, 1, 255, 1, 0, 5, 111, 1, 255, 1, 111, 1, 0, 6, 197, 1, 153, 1, 0, 2, 153, 1, 197, 1, 0, 5, 111, 1, 255, 1, 0, 7, 255, 1, 111, 1, 0, 2, 153, 1, 197, 1, 0, 5, 111, 1, 255, 1, 0, 6, 36, 1, 255, 1, 36, 1, 0, 2, 197, 1, 153, 1, 255, 12, 0, 1, 111, 1, 255, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 5, 111, 1, 255, 1, 0, 6, 197, 1, 153, 1, 0, 2, 111, 1, 255, 1, 36, 1, 0, 5, 111, 1, 255, 1, 0, 7, 153, 1, 255, 1, 0, 1, 197, 2, 0, 6, 111, 1, 255, 1, 0, 8, 111, 1, 255, 2, 73, 1, 0, 6, 111, 1, 255, 1, 0, 9, 255, 2, 153, 1, 0, 6, 111, 1, 255, 1, 0, 8, 153, 1, 255, 1, 36, 1, 255, 1, 197, 1, 0, 5, 111, 1, 255, 1, 0, 7, 111, 1, 255, 1, 36, 1, 0, 2, 255, 1, 153, 1, 0, 4, 111, 1, 255, 1, 0, 6, 153, 1, 255, 1, 36, 1, 0, 9, 153, 1, 197, 1, 0, 5, 73, 1, 255, 1, 0, 7, 36, 1, 255, 4, 73, 1, 0, 85, };
UINT8 _15111865_27[] = {
0, 89, 153, 1, 197, 1, 0, 18, 153, 1, 255, 1, 111, 1, 0, 18, 197, 1, 255, 1, 0, 9, 255, 18, 197, 1, 0, 6, 153, 1, 255, 1, 0, 18, 197, 2, 0, 18, 197, 2, 0, 18, 197, 2, 0, 18, 255, 11, 36, 1, 0, 8, 255, 1, 153, 1, 0, 7, 111, 1, 255, 1, 36, 1, 0, 7, 36, 1, 255, 1, 111, 1, 0, 7, 153, 1, 255, 1, 36, 1, 0, 7, 73, 1, 255, 1, 73, 1, 0, 7, 153, 1, 255, 1, 0, 8, 153, 1, 255, 1, 0, 8, 153, 1, 255, 1, 0, 8, 255, 1, 153, 1, 0, 8, 197, 2, 0, 7, 111, 1, 255, 1, 73, 1, 0, 8, 197, 2, 0, 7, 255, 1, 197, 1, 0, 9, 255, 1, 153, 1, 0, 6, 153, 1, 255, 1, 36, 1, 0, 8, 36, 1, 255, 1, 153, 1, 0, 5, 111, 1, 255, 1, 111, 1, 0, 9, 153, 1, 255, 1, 36, 1, 0, 4, 111, 1, 255, 1, 111, 1, 0, 5, 197, 1, 255, 5, 73, 1, 0, 4, 73, 1, 255, 1, 73, 1, 0, 77, };
UINT8 _15112628_27[] = {
0, 113, 255, 1, 153, 1, 0, 18, 255, 1, 153, 1, 0, 6, 73, 1, 255, 5, 0, 1, 255, 11, 197, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 6, 255, 1, 153, 1, 0, 6, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 153, 1, 255, 10, 111, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 6, 255, 1, 153, 1, 0, 6, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 73, 1, 255, 12, 0, 1, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 14, 73, 1, 255, 5, 0, 1, 73, 1, 255, 10, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 111, 1, 255, 1, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 111, 1, 255, 1, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 10, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 111, 1, 255, 1, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 111, 1, 255, 1, 0, 2, 73, 1, 255, 5, 0, 1, 73, 1, 255, 10, 0, 2, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 111, 1, 255, 1, 0, 9, 73, 1, 255, 1, 36, 1, 0, 6, 153, 1, 197, 1, 0, 9, 73, 1, 255, 1, 36, 1, 0, 2, 111, 1, 255, 4, 73, 1, 0, 81, };
UINT8 _15118516_27[] = {
0, 89, 111, 1, 255, 1, 36, 1, 0, 17, 111, 1, 255, 1, 36, 1, 0, 17, 111, 1, 255, 1, 36, 1, 0, 17, 111, 1, 255, 1, 36, 1, 0, 5, 197, 1, 0, 11, 111, 1, 255, 1, 111, 1, 0, 4, 153, 1, 255, 1, 111, 1, 0, 2, 197, 1, 255, 5, 197, 1, 0, 1, 111, 1, 255, 2, 0, 3, 111, 1, 255, 1, 111, 1, 0, 8, 153, 1, 197, 1, 0, 1, 111, 1, 255, 2, 73, 1, 0, 1, 111, 1, 255, 1, 153, 1, 0, 9, 255, 1, 111, 1, 0, 1, 111, 1, 255, 2, 197, 1, 111, 1, 255, 1, 197, 1, 0, 9, 73, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 111, 1, 255, 2, 197, 1, 0, 10, 153, 1, 197, 1, 0, 2, 111, 1, 255, 1, 36, 1, 255, 1, 197, 1, 0, 10, 36, 1, 255, 1, 111, 1, 0, 2, 111, 1, 255, 1, 36, 1, 73, 1, 255, 1, 73, 1, 0, 9, 153, 1, 255, 1, 0, 3, 111, 1, 255, 1, 36, 1, 0, 1, 197, 1, 255, 1, 0, 8, 36, 1, 255, 1, 111, 1, 0, 3, 111, 1, 255, 1, 36, 1, 0, 1, 36, 1, 255, 1, 153, 1, 0, 7, 197, 1, 255, 1, 0, 4, 111, 1, 255, 1, 36, 1, 0, 2, 111, 1, 255, 1, 73, 1, 0, 5, 111, 1, 255, 1, 111, 1, 0, 4, 111, 1, 255, 1, 36, 1, 0, 3, 153, 1, 255, 1, 36, 1, 0, 3, 36, 1, 255, 1, 197, 1, 0, 5, 111, 1, 255, 1, 36, 1, 0, 4, 197, 1, 255, 1, 36, 1, 0, 2, 255, 2, 36, 1, 0, 5, 111, 1, 255, 1, 0, 6, 197, 1, 255, 1, 36, 2, 111, 1, 73, 1, 0, 6, 153, 1, 197, 1, 0, 7, 197, 1, 255, 1, 0, 5, 73, 1, 255, 4, 36, 1, 0, 89, };
UINT8 _15121311_27[] = {
0, 101, 73, 1, 255, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 4, 255, 1, 197, 1, 0, 6, 36, 1, 153, 1, 255, 1, 36, 1, 0, 1, 36, 1, 255, 1, 73, 1, 0, 3, 111, 1, 255, 1, 36, 1, 0, 8, 153, 2, 0, 1, 36, 1, 255, 1, 73, 1, 0, 2, 36, 1, 255, 6, 153, 1, 0, 5, 36, 1, 255, 5, 111, 1, 197, 1, 153, 1, 0, 3, 111, 1, 255, 1, 36, 1, 0, 7, 36, 1, 255, 1, 73, 1, 0, 1, 153, 1, 197, 1, 0, 3, 153, 1, 255, 1, 0, 4, 255, 1, 36, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 1, 255, 9, 36, 2, 111, 1, 255, 1, 111, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 1, 153, 2, 0, 1, 73, 1, 255, 1, 36, 1, 0, 2, 73, 1, 255, 1, 36, 1, 255, 5, 73, 1, 255, 1, 153, 1, 0, 1, 153, 2, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 1, 153, 2, 0, 1, 73, 1, 255, 1, 36, 1, 0, 6, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 1, 153, 2, 0, 1, 73, 1, 255, 1, 36, 1, 0, 2, 73, 1, 255, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 1, 153, 2, 0, 1, 73, 1, 255, 1, 36, 1, 0, 2, 111, 1, 255, 1, 153, 1, 255, 5, 153, 1, 255, 8, 36, 1, 0, 2, 153, 1, 197, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 4, 73, 1, 255, 1, 36, 1, 0, 2, 255, 1, 111, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 5, 73, 1, 255, 1, 0, 1, 36, 1, 255, 1, 73, 1, 0, 2, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 5, 111, 1, 255, 1, 0, 1, 111, 1, 255, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 2, 255, 1, 153, 1, 0, 5, 111, 1, 255, 1, 0, 1, 197, 2, 0, 3, 36, 1, 255, 1, 73, 1, 0, 2, 197, 1, 153, 1, 0, 5, 197, 1, 153, 1, 0, 1, 255, 1, 111, 1, 0, 3, 36, 1, 255, 1, 73, 1, 0, 2, 73, 1, 255, 7, 0, 81, };
UINT8 _15121803_27[] = {
0, 101, 73, 1, 255, 1, 0, 5, 111, 1, 255, 1, 0, 4, 36, 1, 255, 1, 73, 1, 0, 4, 36, 1, 153, 1, 255, 1, 73, 1, 0, 2, 36, 1, 255, 2, 197, 1, 0, 3, 73, 1, 255, 1, 0, 7, 111, 1, 255, 1, 0, 2, 197, 1, 153, 1, 0, 1, 197, 2, 0, 2, 153, 2, 0, 10, 111, 1, 153, 1, 0, 3, 197, 2, 0, 1, 197, 1, 255, 5, 0, 5, 73, 1, 153, 1, 0, 5, 255, 1, 111, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 36, 1, 255, 1, 0, 2, 73, 1, 197, 1, 255, 6, 0, 1, 111, 1, 255, 1, 36, 1, 0, 1, 111, 1, 255, 1, 0, 1, 36, 1, 153, 1, 255, 1, 73, 1, 255, 1, 0, 8, 197, 1, 255, 1, 73, 1, 0, 1, 111, 1, 197, 1, 0, 3, 111, 1, 255, 1, 0, 3, 73, 1, 197, 1, 0, 3, 73, 1, 153, 1, 197, 1, 111, 1, 0, 1, 153, 2, 0, 5, 73, 1, 255, 1, 0, 1, 36, 1, 255, 1, 36, 1, 0, 1, 255, 2, 73, 1, 153, 2, 0, 1, 197, 1, 111, 1, 0, 6, 255, 1, 73, 1, 0, 1, 255, 1, 73, 1, 36, 1, 255, 1, 36, 1, 0, 1, 111, 1, 197, 1, 0, 1, 255, 1, 73, 1, 0, 6, 197, 1, 153, 1, 0, 1, 197, 1, 111, 2, 197, 1, 0, 2, 73, 1, 255, 1, 73, 1, 255, 1, 0, 4, 153, 2, 0, 1, 111, 1, 255, 1, 0, 1, 153, 2, 197, 1, 111, 1, 0, 3, 255, 2, 153, 1, 0, 4, 197, 2, 0, 1, 73, 1, 255, 1, 73, 1, 0, 1, 73, 1, 255, 1, 36, 1, 0, 3, 153, 1, 255, 1, 36, 1, 0, 3, 36, 1, 255, 1, 111, 1, 0, 5, 111, 1, 197, 1, 0, 4, 153, 1, 255, 1, 73, 1, 0, 3, 73, 1, 255, 1, 36, 1, 0, 3, 153, 1, 255, 5, 0, 1, 111, 1, 255, 1, 197, 1, 255, 1, 0, 3, 153, 1, 197, 1, 0, 1, 153, 1, 255, 2, 111, 1, 0, 5, 73, 1, 255, 1, 73, 1, 0, 1, 255, 1, 153, 1, 0, 2, 197, 1, 153, 1, 0, 9, 73, 1, 255, 1, 111, 1, 0, 2, 36, 1, 255, 1, 111, 1, 0, 1, 255, 1, 111, 1, 0, 9, 255, 1, 111, 1, 0, 4, 36, 1, 255, 1, 0, 80, };
LATTICE lattice_array[] = {
        {46, 5, _46_27},
        {49, 12, _49_27},
        {15041929, 20, _15041929_27},
        {15050173, 20, _15050173_27},
        {15111865, 20, _15111865_27},
        {15112628, 20, _15112628_27},
        {15118516, 20, _15118516_27},
        {15121311, 20, _15121311_27},
        {15121803, 20, _15121803_27},
};

FONT_INFO MyFontArray ={
    27,
    9,
    lattice_array   //1.水光潋滟晴方好
};
//===================UTF-8 汉字 字模 end================================================
//========= Add for UTF-8 Chinese char ==============
//Funciton Name: get_lattice
//Input:
//Output:
//Description: 获得utf8汉字点阵字模
LATTICE* get_lattice(FONT_INFO* font, UINT32 utf8_code)
{
	INTN first = 0;
	INTN last = font->count - 1;
	INTN middle = (first + last) / 2;
	while (first <= last)
	{
		if (font->lattice_array[middle].utf8_code < utf8_code)
			first = middle + 1;
		else if (font->lattice_array[middle].utf8_code == utf8_code)
		{
			return &font->lattice_array[middle];
		}
		else
		{
			last = middle - 1;
		}
		middle = (first + last) / 2;
	}
	return 0;
}

//Funciton Name: draw_lattice
//Input:
//Output:
//Description:
VOID draw_lattice(UINTN x, UINTN y, UINT8 width, UINT8 height, UINT8* p_data, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *font_color)
{
	// unsigned int r, g, b, rgb;
	UINT8 blk_value = *p_data++;
	UINT8 blk_cnt = *p_data++;
  UINT8 x_, y_;
  
	for (y_ = 0; y_ < height; y_++)
	{
		for (x_ = 0; x_ < width; x_++)
		{
			if(blk_value)
        putpixel((x + (UINTN)x_), (y + (UINTN)y_), font_color);
      
			if (--blk_cnt == 0)
			{//reload new block
				blk_value = *p_data++;
				blk_cnt = *p_data++;
			}
		}
	}
}

//Funciton Name: draw_single_char
//Input:
//Output:
//Description:
UINT8 draw_single_char(UINT32 utf8_code, UINTN x, UINTN y, FONT_INFO* font, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *font_color)
{
  LATTICE *p_lattice;
  // unsigned int error_color = 0xFFFFFFFF;
	if (font)
	{
		p_lattice = get_lattice(font, utf8_code);
		if (p_lattice)
		{
			draw_lattice(x, y, p_lattice->width, font->height, p_lattice->pixel_gray_array, font_color);
			return p_lattice->width;
		}
	}
	else
	{
    return 0;
  }
  return 0;
}

VOID draw_string(UINT8 *str, UINTN x, UINTN y, FONT_INFO *font, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *font_color)
{
  UINT8 temp;
  UINT8 *ptr;
  // UINT32 i;
  UINT32 char_utf8;
  UINTN cur_x;
  ptr = (UINT8 *)str;
  cur_x = x;
  while('\0' != *ptr)
  {
    //1 get utf-8 code from str
    temp = ptr[0];
    if(temp > 128) //汉字
    {
      char_utf8 = (((UINT32)ptr[0]) << 16) + (((UINT32)ptr[1]) << 8) + (UINT32)ptr[2];
	    // char_utf8 = (((UINT32)ptr[0]) * 256 *256) + (((UINT32)ptr[1]) *256) + (UINT32)ptr[2];
      ptr += 3;
    }
    else
    {
      char_utf8 = (UINT32)ptr[0];
      ptr += 1;
    }
    //2 display a char
    cur_x += (UINTN)draw_single_char(char_utf8, cur_x, y, font, font_color);
  }
    
}

//在单色的背景上显示透明字符串
VOID draw_string_alpha(UINT8 *str, UINTN x, UINTN y, FONT_INFO *font, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *font_color,EFI_GRAPHICS_OUTPUT_BLT_PIXEL *bg_color,UINT16 Alpha)
{
  UINT8 temp;
  UINT8 *ptr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL ImageOverlayArea;
  // UINT32 i;
  UINT32 char_utf8;
  UINTN cur_x;
  ptr = (UINT8 *)str;
  cur_x = x;
  while('\0' != *ptr)
  {
    //1 get utf-8 code from str
    temp = ptr[0];
    if(temp > 128) //汉字
    {
      char_utf8 = (((UINT32)ptr[0]) << 16) + (((UINT32)ptr[1]) << 8) + (UINT32)ptr[2];
	    // char_utf8 = (((UINT32)ptr[0]) * 256 *256) + (((UINT32)ptr[1]) *256) + (UINT32)ptr[2];
      ptr += 3;
    }
    else
    {
      char_utf8 = (UINT32)ptr[0];
      ptr += 1;
    }
    //2 display a char
    //Alpha混合公式如下：(A覆盖在B上) 对两段内存进行处理,选取Alpha最大分母16,便于计算 
	//                  R(C)=(1-alpha)*R(B) + alpha*R(A)
	//                  G(C)=(1-alpha)*G(B) + alpha*G(A)
	//                  B(C)=(1-alpha)*B(B) + alpha*B(A)
    ImageOverlayArea.Blue = font_color->Blue;
    ImageOverlayArea.Red = font_color->Red;
    ImageOverlayArea.Green = font_color->Green;
    ImageOverlayArea.Reserved = font_color->Reserved;
    ImageOverlayArea.Blue = (UINT8)(((16 - Alpha) * bg_color->Blue + Alpha * ImageOverlayArea.Blue) >> 4);
    ImageOverlayArea.Red = (UINT8)(((16 - Alpha) * bg_color->Red + Alpha * ImageOverlayArea.Red) >> 4);
    ImageOverlayArea.Green = (UINT8)(((16 - Alpha) * bg_color->Green + Alpha * ImageOverlayArea.Green) >> 4);
    ImageOverlayArea.Reserved = (UINT8)(((16 - Alpha) * bg_color->Reserved + Alpha * ImageOverlayArea.Reserved) >> 4);
    cur_x += (UINTN)draw_single_char(char_utf8, cur_x, y, font, &ImageOverlayArea);
  }
    
}
